/*
 * To change this template, choose Tools | Templates
 * and open the template in the editor.
 */

package main.KBProcess;

import java.io.File;
import java.io.FileNotFoundException;
import java.io.IOException;
import java.util.Set;
import javax.xml.parsers.DocumentBuilderFactory;
import javax.xml.parsers.ParserConfigurationException;
import main.KBProcess.Element.ElementType;
import main.Ontology.DefaultElementOntologyFactory;
import main.Ontology.ElementOntologyFactory;

import org.w3c.dom.Document;
import org.w3c.dom.Element;
import org.w3c.dom.NamedNodeMap;
import org.w3c.dom.Node;
import org.w3c.dom.NodeList;
import org.xml.sax.SAXException;

/**
 *
 * @author Isaac Osesina
 */
public class UTEES_Parser_DOM {

    private Document doc = null;
    private Element docEle;
    String kbFilePath;
    KnowledgeBase thisKB;
    int KBCharCnt = 0;
    UTEES_MatchTable documentOntology;
    String ontologyFileName;
    Set<Integer> docsToSkip;
    Set<Integer> docsToAccept;
    
    private ElementOntologyFactory elementOntologyFactory;
    
    public UTEES_Parser_DOM(ElementOntologyFactory elementOntologyFactory) {
    	this.elementOntologyFactory = elementOntologyFactory;
    }

    public void readKB(File KBFile, UTEES_MatchTable docOntology, Set<Integer> docsToSkip, Set<Integer> docsToAccept) throws FileNotFoundException
    {
        if (!KBFile.exists())
        {
            String errorMsg = "Error- Can't open " + KBFile;
            throw new FileNotFoundException(errorMsg);
        }
        this.documentOntology = docOntology;
        this.ontologyFileName = docOntology.getFileName();
        this.docsToSkip = docsToSkip;
        this.docsToAccept = docsToAccept;
        DOMParser(KBFile);
    }

    private void DOMParser(File KBFile)
    {
        try
        {
                doc = parserXML(KBFile);
                //get rootElement
                docEle = doc.getDocumentElement();

                create_UTEES_KB_Objects(doc, 0);
        }
        catch(Exception error)
        {
                error.printStackTrace();
        }
    }

    private Document parserXML(java.io.File file) throws SAXException, IOException, ParserConfigurationException
    {
            return DocumentBuilderFactory.newInstance().newDocumentBuilder().parse(file);
    }

    private void create_UTEES_KB_Objects(Node node, int level)
    {
        thisKB = new DefaultKnowledgeBase();
//        String documentName = documentOntology.getEntryAt(0);
        NodeList nl = docEle.getElementsByTagName("Document");
        if(nl != null && nl.getLength() > 0)
        {
            for(int i = 0 ; i < nl.getLength();i++)
            {
                //get the KBDoc
                Element el = (Element)nl.item(i);

                //get the KBDocument object
                KnowledgeBaseDocument kbDoc  = create_KBDoc(el);
                if(kbDoc != null) {
                    thisKB.addKBDoc(kbDoc);
                }
            }
        }
//        System.out.println(thisKB.getKBSize());
    }

    private KnowledgeBaseDocument create_KBDoc(Element el)
    {
        String docType = el.getTagName();
        NamedNodeMap attrs = el.getAttributes();
        String docLanguage = attrs.item(2).getNodeValue();
        String docCategory = attrs.item(0).getNodeValue();
        String id = attrs.item(1).getNodeValue();
        int docID = Integer.parseInt(id);
        if(docsToAccept!=null && !docsToAccept.contains(docID))
            return null;
        if(docsToSkip!=null && docsToSkip.contains(docID))
            return null;
        KnowledgeBaseDocument kbDoc = new DefaultKnowledgeBaseDocument(docID, documentOntology, elementOntologyFactory);
        int entityCnt = 0;
        //for each <KBDoc> element get values of

        
        Node nd = el.getFirstChild();

        int pos = 0;
        StringBuilder docText = new StringBuilder();
        StringBuilder docContext = new StringBuilder();
        nd = nd.getNextSibling();
        while (nd != null)
        {
            if(!nd.getTextContent().matches("[\n]") && !nd.getTextContent().matches("[\r]") && !nd.getTextContent().matches("[\t]") && !nd.getTextContent().matches("[\f]"))
            {
                main.KBProcess.Element element = new DefaultElement(elementOntologyFactory);
                String elementTag = nd.getNodeName();
                String elementValue = nd.getTextContent();
                documentOntology.findMatch(docLanguage + docCategory + "." + elementTag);
                int tagIndex = documentOntology.getMatchIndex();

                element.setType( elementTag.equalsIgnoreCase(main.KBProcess.Element.CONTEXT)? ElementType.CONTEXT:ElementType.ENTITY );
                element.setLabel(elementTag);
                element.setValue(elementValue);
                element.setIndexOf(pos);
                element.setLabelIndex(tagIndex);
                element.setDocID(docID);
                element.setDocumentCategory(docType);
                element.setDocumentLanguage(docLanguage);
                element.setDocumentCategory(docCategory);
                kbDoc.addElement(element);
                docText.append(elementValue);
                if(!elementTag.equalsIgnoreCase("Context"))
                {
                    entityCnt++;
                }
                else
                {
                    docContext.append(elementValue + "|");
                }
//                    System.out.println(value +" Start:"+pos + " Idx:"+labelIndex);
                pos += elementValue.length();
                
            }
            nd = nd.getNextSibling();
        }
        kbDoc.setDocText(docText.toString());
        kbDoc.setDocContext(docContext.toString());
        kbDoc.setEntityCnt(entityCnt);
        KBCharCnt = KBCharCnt + docText.length();



        //System.out.println(KBDoc.getDocText());
        
        return kbDoc;
    }

    public String getOntologyFileName() {return ontologyFileName;}
    
    public Document getDoc() { return doc; }

    public KnowledgeBase getParsedKB() {return thisKB;}

    public int getKBCharCnt(){return KBCharCnt;}


    public static void main(String[] args) throws FileNotFoundException
    {
        String ontologyFileName = "Files/EnglishObituaryV3.txt";
        String KBFileName = "Files/KB200.txt";
        File ontologyFile = new File(ontologyFileName);
        File KBFile = new File(KBFileName);
        UTEES_MatchTable documentOntology = new UTEES_MatchTable(ontologyFile);
        UTEES_Parser_DOM newDOMParser = new UTEES_Parser_DOM(new DefaultElementOntologyFactory());
        newDOMParser.readKB(KBFile, documentOntology, null, null);
    }
}
